<!DOCTYPE html>
<title>Test serialization of specified CSS variable values</title>
<script src="/MochiKit/MochiKit.js"></script>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css" type="text/css">

<style id=style1>#test { }</style>
<style id=style2></style>

<script>
// Values that should be serialized back to the same string.
var values_with_unchanged_specified_value_serialization = [
  "var(--a)",
  "var(--a)",
  "var(--a) ",
  "var( --a ) ",
  "var(--a, )",
  "var(--a,/**/a)",
  "1px var(--a)",
  "var(--a) 1px",
  "something 3px url(whereever) calc(var(--a) + 1px)",
  "var(--a)",
  "var(--a)var(--b)",
  "var(--a, var(--b, var(--c, black)))",
  "var(--a) <!--",
  "--> var(--a)",
  "{ [ var(--a) ] }",
  "[;] var(--a)",
  "var(--a,(;))",
  "VAR(--a)",
  "var(--0)",
  "var(--\\30)",
  "var(--\\d800)",
  "var(--\\ffffff)",
];

// Values that serialize differently, due to additional implied closing
// characters at EOF.
var values_with_changed_specified_value_serialization = [
  ["var(--a",                       "var(--a)"],
  ["var(--a , ",                    "var(--a , )"],
  ["var(--a, ",                     "var(--a, )"],
  ["var(--a, var(--b",              "var(--a, var(--b))"],
  ["var(--a /* unclosed comment",   "var(--a /* unclosed comment*/)"],
  ["var(--a /* unclosed comment *", "var(--a /* unclosed comment */)"],
  ["[{(((var(--a",                  "[{(((var(--a))))}]"],
  ["var(--a, \"unclosed string",    "var(--a, \"unclosed string\")"],
  ["var(--a, 'unclosed string",     "var(--a, 'unclosed string')"],
  ["var(--a) \"unclosed string\\",  "var(--a) \"unclosed string\""],
  ["var(--a) 'unclosed string\\",   "var(--a) 'unclosed string'"],
  ["var(--a) \\",                   "var(--a) \\\ufffd"],
  ["var(--a) url(unclosedurl",      "var(--a) url(unclosedurl)"],
  ["var(--a) url('unclosedurl",     "var(--a) url('unclosedurl')"],
  ["var(--a) url(\"unclosedurl",    "var(--a) url(\"unclosedurl\")"],
  ["var(--a) url(unclosedurl\\",    "var(--a) url(unclosedurl\\\ufffd)"],
  ["var(--a) url('unclosedurl\\",   "var(--a) url('unclosedurl')"],
  ["var(--a) url(\"unclosedurl\\",  "var(--a) url(\"unclosedurl\")"],
];

var style1 = document.getElementById("style1");
var style2 = document.getElementById("style2");

var decl = style1.sheet.cssRules[0].style;

function test_specified_value_serialization(value, expected) {
  // Test setting value on a custom property with setProperty.
  decl.setProperty("--test", value, "");
  is(decl.getPropertyValue("--test"), expected,
     "value with identical serialization set on custom property with setProperty");

  // Test setting value on a custom property via style sheet parsing.
  style2.textContent = "#test { --test:" + value;
  is(style2.sheet.cssRules[0].style.getPropertyValue("--test"), expected,
     "value with identical serialization set on custom property via parsing");

  // Test setting value on a non-custom longhand property with setProperty.
  decl.setProperty("color", value, "");
  is(decl.getPropertyValue("color"), expected,
     "value with identical serialization set on non-custom longhand property with setProperty");

  // Test setting value on a non-custom longhand property via style sheet parsing.
  style2.textContent = "#test { color:" + value;
  is(style2.sheet.cssRules[0].style.getPropertyValue("color"), expected,
     "value with identical serialization set on non-custom longhand property via parsing");

  // Test setting value on a non-custom shorthand property with setProperty.
  decl.setProperty("margin", value, "");
  is(decl.getPropertyValue("margin"), expected,
     "value with identical serialization set on non-custom shorthand property with setProperty");

  // Test setting value on a non-custom shorthand property via style sheet parsing.
  style2.textContent = "#test { margin:" + value;
  is(style2.sheet.cssRules[0].style.getPropertyValue("margin"), expected,
     "value with identical serialization set on non-custom shorthand property via parsing");

  // Clean up.
  decl.removeProperty("--test");
  decl.removeProperty("color");
  decl.removeProperty("margin");
}

function runTest() {
  values_with_unchanged_specified_value_serialization.forEach(function(value) {
    test_specified_value_serialization(value, value);
  });

  values_with_changed_specified_value_serialization.forEach(function(pair) {
    test_specified_value_serialization(pair[0], pair[1]);
  });

  SimpleTest.finish();
}

SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({ set: [["layout.css.variables.enabled", true]] },
                          runTest);
</script>
